from typing import Dict, Any
import cv2
import numpy as np
from paddleocr import PaddleOCR
from app.utils.logger import get_logger

logger = get_logger(__name__)


# 文档方向分类模块
class DocumentOrientationModule:
    _instance = None
    _initialized = False

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super(DocumentOrientationModule, cls).__new__(cls)
        return cls._instance

    def __init__(self):
        if not self._initialized:
            logger.info("Initializing DocumentOrientationModule")
            # 使用PaddleOCR的角度分类功能
            self.ocr = PaddleOCR(use_angle_cls=True, lang="ch")
            self._initialized = True

    def classify(self, image_data: bytes) -> Dict[str, Any]:
        """
        分类文档图像方向

        Args:
            image_data: 图像字节数据

        Returns:
            方向分类结果
        """
        try:
            # 将字节数据转换为OpenCV图像
            nparr = np.frombuffer(image_data, np.uint8)
            img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)

            # 使用OCR的角度分类功能
            result = self.ocr.ocr(img, cls=True)

            # 提取角度信息（通常在result的第一个元素中）
            if result and result[0]:
                # 获取第一个检测到的文本的角度信息
                cls_result = result[0][0][1] if len(result[0]) > 0 else None
                if cls_result and len(cls_result) > 1:
                    angle_info = cls_result[1]  # (角度, 置信度)
                    angle = angle_info[0]
                    confidence = angle_info[1]

                    # 转换角度为方向描述
                    orientation = self._angle_to_orientation(angle)

                    return {
                        "orientation": orientation,
                        "angle": angle,
                        "confidence": confidence
                    }

            # 默认返回
            return {
                "orientation": "up",
                "angle": 0,
                "confidence": 0.0
            }

        except Exception as e:
            raise RuntimeError(f"Document orientation classification failed: {str(e)}")

    def _angle_to_orientation(self, angle: int) -> str:
        """将角度转换为方向描述"""
        angle_map = {
            0: "up",
            90: "right",
            180: "down",
            270: "left"
        }
        return angle_map.get(angle, "up")
